
package com.usian.admin.service.impl

import com.alibaba.fastjson.JSONArray
import com.usian.admin.feign.ArticleFeign1
//import com.usian.admin.feign.ArticleFeign
import com.usian.admin.feign.WemediaFeign
import com.usian.admin.mapper.AdChannelMapper
import com.usian.admin.mapper.AdSensitiveMapper
import com.usian.admin.service.WemediaNewsAutoScanService
import com.usian.common.aliyun.GreeTextScan
import com.usian.common.aliyun.GreenImageScan
import com.usian.common.fastdfs.FastDFSClient
import com.usian.model.admin.dtos.NewsAuthDto
import com.usian.model.article.pojos.ApArticle
import com.usian.model.article.pojos.ApArticleConfig
import com.usian.model.article.pojos.ApArticleContent
import com.usian.model.common.dtos.PageResponseResult
import com.usian.model.common.dtos.ResponseResult
import com.usian.model.common.enums.AppHttpCodeEnum
import com.usian.model.media.pojos.WmNews
import com.usian.model.media.vo.WmNewsVo
import com.usian.utils.common.SensitiveWordUtil
import org.codehaus.jettison.json.JSONObject
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import java.lang.StringBuilder
import java.util.*

typealias mm = MutableMap<String, Any>

@Service
class WemediaNewsAutoScanServiceImpl : WemediaNewsAutoScanService {


    @Autowired
    lateinit var articleFeign: ArticleFeign1

    @Autowired
    lateinit var weMediaFeign: WemediaFeign

    @Autowired
    lateinit var adChannelMapper: AdChannelMapper

    @Autowired
    lateinit var adSensitiveMapper: AdSensitiveMapper

    @Autowired
    lateinit var fastDFSClient: FastDFSClient

    @Autowired
    lateinit var greeTextScan: GreeTextScan

    @Autowired
    lateinit var greenImageScan: GreenImageScan

    @Value("\${fdfs.url}")
    lateinit var basePath: String

    override fun autoScanByMediaNewsId(id: Int) {
        if (id == null) {
            println("审核id为空")
            return
        }
        val wmNews: WmNews = weMediaFeign.findById(id)
        if (wmNews == null) {
            println("文章id不存在$id")
            return
        }
        //第一次审核的时候是进不了这个判断的，只有阿里云审核状态是review将状态改为3，人工审核通过状态改为4，
        // 然后xxljob定时扫描待发布文章时，顺带扫描了状态为人工审核通过的情况。
        if (wmNews.status.toInt() == 4) {
            saveAppArticle(wmNews)
            return
        }
        //待发布&&时间已经到了的
        if (wmNews.status.toInt() == 8 && wmNews.publishTime.time <= System.currentTimeMillis()) {
            saveAppArticle(wmNews)
            return
        }
        //当自媒体用户提交文章，kafka将文章id发过来后，消费者调用该方法进行第一次文章审核
        if (wmNews.status.toInt() == 1) {
            var contentAndImagesResult: mm = handleTextAndImages(wmNews)
            handleTextScan(contentAndImagesResult["content"].toString(), wmNews)
            handleImagesScan(contentAndImagesResult["images"] as MutableList<String>, wmNews)
            handleSensitive(contentAndImagesResult["content"].toString(), wmNews)
            if(wmNews.publishTime.time > System.currentTimeMillis()){//发布时间没到
                updateWmNews(wmNews,8,"审核通过，待发布")
            }
            saveAppArticle(wmNews)
        }
    }

    private fun handleSensitive(text: String, wmNews: WmNews) {
        val sensitiveList = adSensitiveMapper.findAllSensitive()
        SensitiveWordUtil.initMap(sensitiveList)
        val matchWords = SensitiveWordUtil.matchWords(text)
        if (matchWords.isNotEmpty()){
            println("敏感词过滤没有通过，包含了敏感词:$matchWords")
            updateWmNews(wmNews,2,"文章中包含了敏感词")
            return
        }
    }

    private fun handleImagesScan(imageList: MutableList<String>, wmNews: WmNews) {
        try {
            if (imageList != null && imageList.size != 0) {
                greenImageScan.imageScan(mutableListOf<ByteArray>().apply {
                    imageList.forEach {
                        var newPath = it.replace(basePath, "")
                        var index = newPath.indexOf("/")
                        var groupName = newPath.substring(0, index)
                        var pathName = newPath.substring(index + 1)
                        val download: ByteArray = fastDFSClient.download(groupName, pathName)
                        add(download)
                    }
                }).let {
                    it["suggestion"].let {
                        if (it != "pass") {
                            if (it == "block") {
                                updateWmNews(wmNews, 2, "文章中图片有违规")
                                return
                            }
                            if (it == "review") {
                                updateWmNews(wmNews, 3, "文章图片有不确定元素")
                                return
                            }
                        }
                    }

                }
            }
        } catch (e: Exception) {
            println(e.message)
            return
        }
    }

    private fun handleTextScan(any: String, wmNews: WmNews) {
        try {
            val map = greeTextScan.greeTextScan(any)
            map["suggestion"].apply {
                if (this != "pass") {
                    if (this == "block") {
                        updateWmNews(wmNews, 2, "文本中有敏感词")
                        return
                    }
                    if (this == "review") {
                        updateWmNews(wmNews, 3, "阿里云也不知道你行不行")
                        return
                    }
                }
            }
        } catch (e: Exception) {
            println(e.message)
            return
        }
    }

    private fun handleTextAndImages(news: WmNews): mm {
        var imageList = mutableListOf<String>()
        var text = StringBuilder()
        //将文章内容中的图片加到集合中
        news.content.apply {
            val array = JSONArray.parseArray(this)
            array.forEach {
                var objects = JSONObject(it.toString())
                if (objects.get("type") == "text") {
                    text.append(objects.get("value"));
                }
                if (objects.get("type") == "image") {
                    imageList.add(objects.get("value").toString())
                }
            }
        }
        //将封面图片加到集合中
        if (news.images.isNotBlank() && news.type.toInt() != 0)
            imageList.addAll(news.images.split(","))
        return mutableMapOf("content" to text, "images" to imageList)
    }

    private fun saveAppArticle(wmNews: WmNews) {
        val apArticle: ApArticle = saveArticle(wmNews)
        saveArticleConfig(apArticle)
        saveArticleContent(apArticle, wmNews)
        updateWmNews(wmNews, 9.toShort())
    }

    private fun updateWmNews(wmNews: WmNews, articleStatus: Short, refuseReason: String = "审核通过") = weMediaFeign.updateWmNews(wmNews.apply {
        status = articleStatus
        reason = refuseReason
    })

    private fun saveArticleContent(apArticle: ApArticle, wmNews: WmNews) = articleFeign.saveArticleContent(ApArticleContent().apply {
        content = wmNews.content
        articleId = apArticle.id
    })

    private fun saveArticleConfig(apArticle: ApArticle) = articleFeign.saveArticleConfig(ApArticleConfig().apply {
        articleId = apArticle.id
        isComment = true
        isDelete = false
        isForward = true
        isDown = true
    })

    private fun saveArticle(wmNews: WmNews): ApArticle = articleFeign.saveArticle(ApArticle().apply {
        wmNews.let {
            title = it.title
            layout = it.type
            images = it.images
            createdTime = Date()
            var wmUser = weMediaFeign.findWmUserById(it.userId.toInt())
            if (wmUser != null) {
                articleFeign.selectAuthorByName(wmUser.name).let {i ->
                    if (i != null) {
                        authorId = i.id.toLong()
                        authorName = i.name
                    }
                }
            }
            adChannelMapper.selectById(it.channelId).let { c ->
                if (c != null) {
                    channelId = c.id
                    channelName = c.name
                }
            }
        }
    })

    override fun findNews(dto: NewsAuthDto?): PageResponseResult {
        //分页查询
        var findList = weMediaFeign.findList(dto)
        //有图片需要显示，需要fasfdfs服务器地址
        findList.setHost(basePath);
        return findList;
    }

    override fun findOne(id: Int?): ResponseResult<*> {
        //1参数检查
        if(id == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2查询数据
        val wmNewsVo : WmNewsVo = weMediaFeign.findWmNewsVo(id);
        //结构封装
        val responseResult : ResponseResult<Any> = ResponseResult.okResult(wmNewsVo)
        responseResult.setHost(basePath);
        return responseResult;
    }

    override fun updateStatus(type: Int?, dto: NewsAuthDto?): ResponseResult<*> {
        //1.参数检查
        if(dto == null || dto.getId() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.查询文章
        val wmNews : WmNews  = weMediaFeign.findById(dto.getId());
        if(wmNews == null ){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //3.审核没有通过
        if(type!!.equals(0)){
            updateWmNews(wmNews,2,dto.getMsg());
        }else if(type.equals(1)){
            //4.人工审核通过
            updateWmNews(wmNews,4,"人工审核通过");
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}


